<template>
  <div class="l-rblock l-tab-page view-page">
    <l-layout class="l-tab-page" :bottom="300">
      <div
        :class="['l-auto-window', { 'only-tabs': sqls.length == 1 }]"
        style="background-color: #fff; padding: 4px; padding-bottom: 0"
      >
        <el-tabs
          v-model="activeName"
          @tab-click="handleClickTab"
          @edit="removeChildSql"
          type="card"
        >
          <el-tab-pane
            :key="index"
            v-for="(item, index) in sqls"
            class="flex flex-column"
            :label="item.label"
            :name="`${index}`"
            :closable="item.type == 2"
            style="overflow: hidden;"
          >
            <div class="top-panel">
              <div class="top-panel__item">
                <el-select
                  style="width: 100%"
                  size="mini"
                  v-model="item.dbCode"
                  :placeholder="$t('please select数据库')"
                >
                  <el-option-group
                    v-for="group in lr_dblinkTree"
                    :key="group.id"
                    :label="group.label"
                  >
                    <el-option
                      v-for="item in group.children"
                      :key="item.id"
                      :label="item.label"
                      :value="item.id"
                    >
                    </el-option>
                  </el-option-group>
                </el-select>
              </div>
              <div class="top-panel__item" v-if="item.type == 2">
                <el-input
                  v-model="item.paramName"
                  size="mini"
                  :placeholder="$t('用与主query条件的参数名')"
                ></el-input>
              </div>
              <div>
                <el-tooltip
                  :content="$t('query')"
                  :enterable="false"
                  placement="bottom"
                  ><el-button
                    class="learun-text-btn"
                    type="text"
                    icon="learun-icon-play-base"
                    @click="loadTableData"
                  />
                </el-tooltip>
              </div>
              <div>
                <el-tooltip
                  :content="$t('美化')"
                  :enterable="false"
                  placement="bottom"
                  ><el-button
                    class="learun-text-btn"
                    type="text"
                    icon="el-icon-magic-stick"
                    @click="handleFormatter"
                  />
                </el-tooltip>
              </div>

              <div class="right-btn">
                <el-tooltip
                  :content="$t('添加子query参数')"
                  :enterable="false"
                  placement="bottom"
                  ><el-button
                    class="learun-text-btn"
                    type="text"
                    icon="learun-icon-add"
                    @click="addChildSql"
                  />
                </el-tooltip>
              </div>
            </div>
            <div class="l-rblock" style="padding-bottom:30px;">
              <l-code-mirror
                :ref="`codeMirror${index}`"
                v-model="item.sql"
                mode="text/x-sql"
                v-if="`${index}` == activeName"
              ></l-code-mirror>
            </div>
          </el-tab-pane>
        </el-tabs>
      </div>

      <template #bottom>
        <div v-if="tableColumns.length > 0" class="l-rblock">
          <l-table
            ref="mainTable"
            :columns="tableColumns"
            :dataSource="tableData"
            :loading="tableLoading"
            :isPage="true"
            :pageTotal="tableTotal"
            :tablePage.sync="tableCurrentPage"
            @loadPageData="turnTablePage"
          >
          </l-table>
        </div>
      </template>
    </l-layout>
    <div :class="['info-wraper', { opened: infoWraperOpen }]">
      <el-form
        v-show="infoWraperOpenType == 'info'"
        style="padding: 10px 10px 0 10px"
        :model="formData"
        :rules="rules"
        size="mini"
        ref="form"
      >
        <el-form-item :label="$t('名称')" prop="f_Name">
          <el-input
            v-model="formData.f_Name"
            :placeholder="$t('please enter')"
          ></el-input>
        </el-form-item>
        <el-form-item :label="$t('编码')" prop="f_Code">
          <el-input
            v-model="formData.f_Code"
            :placeholder="$t('please enter')"
          ></el-input>
        </el-form-item>
        <el-form-item :label="$t('分类')" prop="f_Category">
          <l-tree-select
            v-model="formData.f_Category"
            :options="lr_dataItemTree(lr_dataItem['datasourceType'])"
          />
        </el-form-item>
        <el-form-item :label="$t('备注')" prop="f_Description">
          <el-input
            type="textarea"
            v-model="formData.f_Description"
            rows="6"
          ></el-input>
        </el-form-item>
      </el-form>
      <template v-if="infoWraperOpenType == 'order'">
        <el-form
          style="padding: 10px 10px 0 10px"
          size="mini"
          v-if="orders.length > 0"
        >
          <div
            class="learun-row-form-input"
            :key="index"
            v-for="(item, index) in orders"
          >
            <el-form-item :label="$t('字段')" style="margin-bottom: 8px">
              <el-autocomplete
                v-model="item.field"
                :fetch-suggestions="querySearchAsync"
              ></el-autocomplete>
            </el-form-item>

            <el-form-item :label="$t('倒序')" style="margin-bottom: 8px">
              <el-switch v-model="item.isDESC"></el-switch>
            </el-form-item>
            <el-button
              :title="$t('Delete')"
              @click="handleRemoveOrder(index)"
              class="learun-row-form-input-delete"
              circle
              plain
              size="mini"
              type="danger"
            >
              <i class="el-icon-close"></i>
            </el-button>
          </div>
        </el-form>
        <div v-if="orders.length > 0" class="mt-8" style="padding-left: 10px">
          <el-button type="primary" size="mini" @click="handleAddOrder">{{
            $t("添加排序字段")
          }}</el-button>
        </div>
        <div v-else class="learun-empty">
          <el-empty :description="$t('还没有添加排序字段')" />
          <el-button type="primary" size="mini" @click="handleAddOrder">{{
            $t("添加一个")
          }}</el-button>
        </div>
      </template>
      <template v-else-if="infoWraperOpenType == 'field'">
        <div v-if="columns.length > 0" style="padding: 10px">
          <div class="field-row" v-for="field in columns" :key="field.prop">
            <div :class="['field-row-header', getTypeClass(field)]">
              {{ getTypeName(field) }}
            </div>
            <div class="field-row-content">{{ getColNames(field) }}</div>
          </div>
        </div>
        <div v-else class="learun-empty">
          <el-empty :description="$t('暂无字段信息,请在左侧选择数据表')" />
        </div>
      </template>
    </div>
    <div class="right-side">
      <div
        :class="['vertical-btn', { opened: infoWraperOpenType == 'info' }]"
        @click="handleClickRightSideBtn('info')"
      >
        {{ $t('基础信息') }}
      </div>
      <div
        :class="['vertical-btn', { opened: infoWraperOpenType == 'order' }]"
        @click="handleClickRightSideBtn('order')"
      >
        {{ $t('排序字段') }}
      </div>
      <div
        :class="['vertical-btn', { opened: infoWraperOpenType == 'field' }]"
        @click="handleClickRightSideBtn('field')"
      >
        {{ $t('字段信息') }}
      </div>
    </div>
  </div>
</template>
<script>
const api = window.$api.data.dbsource;
export default {
  data() {
    return {
      activeName: "0",

      infoWraperOpen: true,
      infoWraperOpenType: "info",
      tableMap: {},

      formData: {
        f_Name: "",
        f_Code: "",
        f_Category: "",
        f_Description: "",
      },
      rules: {
        f_Name: [{ required: true, message: "please enter" }],
        f_Category: [{ required: true, message: "please select" }],
        f_Code: [
          { required: true, message: "please enter" },
          {
            validator: this.lr_existDbFiled,
            keyValue: () => {
              return this.formData.f_Id;
            },
            tableName: "lr_base_datasource",
            keyName: "f_Id",
            trigger: "null",
          },
        ],
      },

      sqls: [
        {
          label: this.$t("主query"),
          sql: "",
          dbCode: "lrsystemdb",
        },
      ],

      orders: [],
      columns: [],

      tableLoading: false,

      tables: {},
      tableColumns: [],
      tableData: [],
      tableTotal: 0,
      tablePageSize: 50,
      tableCurrentPage: 1,
    };
  },
  created() {
    this.lr_loadDblink();
  },
  computed: {
    currentConfig() {
      return this.sqls[parseInt(this.activeName)];
    },
  },
  methods: {
    handleClickRightSideBtn(type) {
      if (this.infoWraperOpenType != type) {
        this.infoWraperOpenType = type;
        this.infoWraperOpen = true;
      } else {
        this.infoWraperOpenType = "";
        this.infoWraperOpen = false;
      }
    },
    handleFormatter() {
      var name = `codeMirror${this.activeName}`;
      this.$refs[name][0].sqlFormatter();
    },
    addChildSql() {
      const child = {
        id: this.$uuid(),
        label: this.$t(`子query`),
        sql: "",
        dbCode: "lrsystemdb",
        type: "2",
        paramName: "",
      };
      this.sqls.push(child);
      this.activeName = `${this.sqls.length - 1}`;

      const tableInfo = {
        tableColumns: [],
        tableData: [],
        tableTotal: 0,
        tablePageSize: 50,
        tableCurrentPage: 1,
      };
      this.setTable(tableInfo);
    },
    removeChildSql(value, action) {
      if (action === "remove") {
        this.$confirm(this.$t("是否Delete该子query?"), this.$t("Tips"), {
          confirmButtonText: this.$t("confirm"),
          cancelButtonText: this.$t("cancel"),
          type: "warning",
        })
          .then(() => {
            const id = this.sqls[value].id;
            this.sqls.splice(value, 1);
            delete this.tables[id];
            this.activeName = "0";
            this.setTable(this.tables[this.sqls[0].id || "main"]);
          })
          .catch(() => {});
      }
    },
    handleClickTab() {
      let id = this.sqls[parseInt(this.activeName)].id || "main";
      this.setTable(
        this.tables[id] || {
          tableColumns: [],
          tableData: [],
          tableTotal: 0,
          tablePageSize: 50,
          tableCurrentPage: 1,
        }
      );
    },

    validateSqls(sqls) {
      for (let i = 0, len = sqls.length; i < len; i++) {
        const { sql, type, paramName, label, dbCode } = sqls[i];
        if (!dbCode) {
          this.$message({
            type: "error",
            message: `${this.$t("please select")}${label}${this.$t("的数据库")}`,
          });
          return false;
        }
        if (!sql) {
          this.$message({
            type: "error",
            message: `${this.$t("请填写")}${label}${this.$t("的sql语句")}`,
          });
          return false;
        }

        if (type == "2" && sqls.length > 1) {
          if (!paramName) {
            this.$message({
              type: "error",
              message: `${this.$t("请填写")}${label}${this.$t("的参数名")}`,
            });
            return false;
          }
        }
      }
      return true;
    },

    async loadTableData(isNotFirst) {
      let sqls;
      if (this.activeName == "0") {
        sqls = this.sqls;
      } else {
        sqls = [this.sqls[parseInt(this.activeName)]];
      }

      if (!this.validateSqls(sqls)) {
        return;
      }

      if (!isNotFirst) {
        this.tableCurrentPage = 1;
      }
      this.tableLoading = true;
      let queryData = {
        rows: this.tablePageSize,
        page: this.tableCurrentPage,
      };

      const res = await this.$awaitWraper(
        api.getViewPageByEntity(queryData, {
          f_DbId: "learun_view",
          f_Sql: this.getSettingJson(sqls),
        })
      );
      if (res) {
        //console.log(res.cols,'res.cols');
        this.setColumns(res.cols.map(t=>({...t,minWidth:10*t.label.length})));
        this.tableData = res.rows;
        this.tableTotal = res.records;
      } else {
        this.setColumns([]);
        this.tableData = [];
        this.tableTotal = [];
      }

      const tableInfo = {
        tableColumns: this.tableColumns,
        tableData: this.tableData,
        tableTotal: this.tableTotal,
        tablePageSize: this.tablePageSize,
        tableCurrentPage: this.tableCurrentPage,
      };
      this.tables[sqls[0].id || "main"] = tableInfo;

      this.tableLoading = false;
    },
    turnTablePage({ rows }) {
      this.tablePageSize = rows;
      this.loadTableData(true);
    },
    setColumns(columns) {
      if (this.activeName == "0") {
        this.columns = columns;
      }
      this.tableColumns = columns;
      this.$refs.mainTable && this.$refs.mainTable.doLayout();
    },
    setTable(tableInfo) {
      this.tableColumns = tableInfo.tableColumns;
      this.$refs.mainTable && this.$refs.mainTable.doLayout();
      this.tableData = tableInfo.tableData;
      this.tableTotal = tableInfo.tableTotal;
      this.tablePageSize = tableInfo.tablePageSize;
      this.tableCurrentPage = tableInfo.tableCurrentPage;
    },

    getSettingJson(sqls) {
      const settingJson = {
        orders: this.$deepClone(this.orders),
        type: "sql",
        sqls: sqls,
        columns: this.columns.map((t) => ({
          prop: t.prop,
          label: t.label,
          csType: t.csType,
        })),
      };
      return this.lr_AESEncrypt(JSON.stringify(settingJson), "David");
    },

    /**排序字段设置 */
    handleAddOrder() {
      this.orders.push({
        field: "",
        isDESC: false,
      });
    },
    handleRemoveOrder(index) {
      this.orders.splice(index, 1);
    },
    async querySearchAsync(queryString, cb) {
      const list = this.columns;
      const res = queryString
        ? list.filter(
            (t) =>
              t.prop.indexOf(queryString) != -1 ||
              t.label.indexOf(queryString) != -1
          )
        : list;
      cb(
        res.map((t) => {
          return { value: this.getColNames(t) };
        })
      );
    },

    /**获取字段信息*/
    getColNames({ prop, label }) {
      let name = prop;
      if (prop != label) {
        name = `${prop}(${label})`;
      }

      return name;
    },
    getTypeClass({ csType }) {
      switch (csType.toLowerCase()) {
        case "string":
        case "text":
          return "str";
        case "int":
        case "int64":
        case "int32":
        case "int16":
        case "long":
        case "short":
        case "decimal":
        case "double":
        case "float":
          return "num";
        case "datetime":
          return "date";
        case "bool":
          return "bool";
        default:
          return "";
      }
    },
    getTypeName({ csType }) {
      switch (csType.toLowerCase()) {
        case "string":
        case "text":
          return "字符";
        case "int":
        case "int64":
        case "int32":
        case "int16":
        case "long":
        case "short":
        case "decimal":
        case "double":
        case "float":
          return "数字";
        case "datetime":
          return "日期";
        case "bool":
          return "布尔";
        default:
          return csType;
      }
    },

    resetForm() {
      this.formData.f_Id = "";
      this.orders = [];
      this.sqls = [
        {
          label: this.$t("主query"),
          sql: "",
          dbCode: "lrsystemdb",
        },
      ];
      this.$formClear(this.$refs.form);

      this.infoWraperOpenType = "info";
      this.infoWraperOpen = true;

      this.tableData = [];
      this.columns = [];

      const tableInfo = {
        tableColumns: [],
        tableData: [],
        tableTotal: 0,
        tablePageSize: 50,
        tableCurrentPage: 1,
      };
      this.setTable(tableInfo);

      this.$refs.mainTable && this.$refs.mainTable.doLayout();
    },
    // 校验表单
    async validateForm() {
      let valid = await this.$formValidateWraper(this.$refs.form);
      if (valid) {
        if (this.orders.findIndex((t) => !t.field) > -1) {
          this.$message({
            type: "error",
            message: this.$t(`请完善排序字段设置`),
          });
          return false;
        }
        if (!this.validateSqls(this.sqls)) {
          return false;
        }

        const res = await this.$awaitWraper(
          api.getViewPageByEntity(
            {
              rows: 1,
              page: 1,
            },
            {
              f_DbId: "learun_view",
              f_Sql: this.getSettingJson(this.sqls),
            }
          )
        );
        if (!res) {
          return false;
        }
        this.columns = res.cols;
        return true;
      }
      return false;
    },
    setForm(data) {
      this.formData = {
        f_Id: data.f_Id,
        f_Name: data.f_Name,
        f_Code: data.f_Code,
        f_Category: data.f_Category,
        f_Description: data.f_Description,
      };
      if (data.f_DbId == "learun_view" || data.f_DbId == "learun_new_data") {
        const { orders, sqls, columns } = JSON.parse(data.f_Sql);
        this.orders = orders;
        this.columns = columns || [];
        console.log(sqls, "sqls");
        this.sqls = sqls.filter(
          (t) => t.type != "1" && !(t.relations && t.relations.length > 0)
        );
      } else {
        this.sqls[0].sql = data.f_Sql;
        this.sqls[0].dbCode = data.f_DbId;
      }

      this.loadTableData();
    },
    getForm() {
      const postData = {
        f_Name: this.formData.f_Name,
        f_Code: this.formData.f_Code,
        f_Category: this.formData.f_Category,
        f_Description: this.formData.f_Description,

        f_DbId: "learun_view",
        f_Type: 0, // sql视图
        f_Sql: this.getSettingJson(this.sqls),
      };
      return postData;
    },
  },
};
</script>

<style lang="scss" scoped>
@import "@/core/styles/variables.scss";
.view-page {
  display: flex;
}
.right-side {
  position: relative;
  height: 100%;
  width: 32px;
  min-width: 32px;
  background-color: #fff;
  border-left: 1px solid $border-color-base;
  flex-grow: 2;
}
.vertical-btn {
  position: relative;
  color: $heading-color;
  padding: 4px;
  text-align: center;
  border-bottom: 1px solid $border-color-base;
  cursor: pointer;
  &:hover {
    color: $primary-color;
  }
  &.opened {
    color: $primary-color;
    &::after {
      content: "";
      height: 100%;
      width: 1px;
      background-color: #fff;
      position: absolute;
      top: 0;
      left: -1px;
    }
  }
}
.info-wraper {
  height: 100%;
  width: 0;
  transition: 0.3s all;
  background-color: #fff;
  flex-grow: 2;
  opacity: 0;
  overflow: auto;

  &.opened {
    width: 320px;
    min-width: 320px;
    border-left: 1px solid $border-color-base;
    opacity: 1;
  }
}
.top-panel {
  position: relative;
  height: 40px;
  width: 100%;
  background-color: #fff;
  border-bottom: 1px solid $border-color-split;

  display: flex;
  align-items: center;
  padding-left: 8px;

  &__item {
    width: 200px;
    margin-right: 8px;
  }
}
.right-btn {
  position: absolute;
  right: 0;
  top: 0;
  display: flex;
  align-items: center;
  padding-right: 8px;
  height: 100%;
}

.field-row {
  position: relative;
  display: flex;
  height: 40px;
  box-shadow: 0 2px 4px 0 rgb(0 0 0 / 8%);
  border-radius: 2px;
  overflow: hidden;
  margin-bottom: 8px;
  &:last-child {
    margin-bottom: 0;
  }

  &-header {
    width: 40px;
    min-width: 40px;
    height: 100%;
    line-height: 40px;
    text-align: center;
    background-color: $info-color;
    color: #fff;

    // 数字 ，日期， 布尔
    &.str {
      background-color: $primary-color;
    }
    &.num {
      background-color: $success-color;
    }
    &.date {
      background-color: $warning-color;
    }
    &.bool {
      background-color: $error-color;
    }
  }

  &-content {
    border: 1px solid $border-color-base;
    border-left: 0;
    width: 100%;
    height: 100%;
    line-height: 38px;
    padding-left: 8px;
  }
}

.learun-empty {
  position: relative;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;

  .el-empty {
    padding-top: 0;
  }
}
</style>